<template>
  <el-row :gutter="20">
    <el-col :span="6" v-for="role in roleStore.allRoles" :key="role.role_id">
      <el-card>
        <div>{{ role.role_name }} </div>
        <div class="btn-wrapper">
          <el-button type="primary" size="default" @click="beginUpdate(role)">编辑</el-button>
          <el-button type="primary" size="default" @click="beginRoleFuncConfig(role.role_id)">功能分配</el-button>
          <el-button type="primary" size="default" @click="remove(role)">删除</el-button>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card @click="beginAdd">
        <div>+</div>
      </el-card>
    </el-col>
  </el-row>
  <el-dialog v-model="roleEdit.isEdit" title="角色编辑">
    <el-form :model="roleEdit.model" :rules="roleEdit.rules" :ref="(el: any) => roleEdit.formRef = el">
      <el-form-item label="角色名称:" prop="role_name">
        <el-input v-model.trim="roleEdit.model.role_name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button @click="save">确定</el-button>
        <el-button @click="roleEdit.isEdit = false">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
  <el-drawer v-model="roleFuncConfig.isEdit" title="角色功能分配">
    <el-tree :ref="(el: any) => roleFuncConfig.treeRef = el" class="custom_tree" :data="funcStore.allFuncsTreeData"
      :expand-on-click-node="false" :props="{ children: 'children' }" default-expand-all
      show-checkbox node-key="func_id">
      <template #default="{ data,data: { func_id, func_name, func_key, children } }">
        <div class="custom-tree-node">
          <span :class="{ leaf: func_key !== '' }">
            <el-icon style="vertical-algin: middle" :size="20" v-if="func_key != ''" color="#3377cc">
              <Paperclip />
            </el-icon>{{ func_name }}
          </span>
        </div>
      </template>
    </el-tree>
    <template #footer>
      <el-button type="primary" size="default" @click="saveRoleFuncConfig">确定</el-button>
      <el-button type="primary" size="default" @click="roleFuncConfig.isEdit = false">取消</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { onMounted, ref, reactive, nextTick, markRaw, computed, ComputedRef, Raw } from "vue";
import { useRoleStore, useFunc } from "@/store"
import { ElMessageBox, ElMessage, FormRules, FormInstance, ElTree } from "element-plus";



const roleStore = useRoleStore()
const funcStore = useFunc()

const roleEdit = reactive<{ isEdit: boolean; formRef: null | FormInstance; model: HttpPayload.Role; rules: FormRules }>({
  isEdit: false,
  model: { role_id: 0, role_name: "" },
  formRef: null,
  rules: markRaw({
    role_name: [
      {
        validator: (type, value, callback) => {
          if (value === "") callback(new Error("*角色名不能为空"));//非空验证
          else if (value.length < 2 || value.length > 20) //长度验证
            callback(new Error("*角色名长度2-20"));
          else if (roleStore.allRoles.some((role) => role.role_name === value && role.role_id !== roleEdit.model.role_id))//唯一性验证
            callback(new Error("*角色名已存在"));
          else callback();
        },
        trigger: "blur",
      },
    ],
  }),
});
const roleFuncConfig = reactive<{ isEdit: boolean, treeRef: InstanceType<typeof ElTree> | null, model: Raw<{ role_id: number; role_func_ids: string, }> }>({
  isEdit: false,
  treeRef: null,
  model: markRaw({
    role_id: 0,        //点某个角色进行功能分配时在立即赋值更新
    role_func_ids: "" //点击保存的在现去从tree里面去搜素
  })
});

onMounted(() => {
  try {
    roleStore.init()
    funcStore.init()
  } catch (e) {/* */ }
})
const remove = async (role: Vm.Role) => {
  try {
    //问用户是不是确定删除
    await ElMessageBox.confirm(`确定要删除角色:${role.role_name}"" 吗?`, "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });
    // 发ajax从数据库中删除功能
    await roleStore.remove(role.role_id)
    //从allFuncs中删除功能,更新页面
    ElMessage({ type: "success", message: `角色："${role.role_name}"删除成功` });
  } catch (e) {
    /**/
  }
}
const beginAdd = () => {
  roleEdit.formRef?.resetFields();
  roleEdit.model = { role_id: 0, role_name: "" }
  nextTick(() => roleEdit.isEdit = true);
}
const beginUpdate = (role: Vm.Role) => {
  roleEdit.formRef?.resetFields();
  roleEdit.model = { ...role }
  nextTick(() => roleEdit.isEdit = true);
}
const save = async () => {
  try {
    await roleEdit.formRef?.validate();
    await roleStore[roleEdit.model.role_id === 0 ? "add" : "update"](roleEdit.model);
    ElMessage({ type: 'success', message: "角色编辑成功" })
    roleEdit.isEdit = false;
  } catch (e) {/** */ }
}
const beginRoleFuncConfig = async (role_id: number) => {
  try {
    roleFuncConfig.model.role_id = role_id;
    const roleFuncs: Array<Vm.Func> = await roleStore.getRoleFuncs(role_id);
    const checkedKeys: Array<number> = roleFuncs.reduce((result: Array<number>, item) => {
      if (item.func_key !== "") result.push(item.func_id);
      return result;
    }, []);
    nextTick(() => {
      roleFuncConfig.isEdit = true;
      nextTick(() => roleFuncConfig.treeRef?.setCheckedKeys(checkedKeys))
    });
  } catch (e) {/** */ }

}
const saveRoleFuncConfig = async () => {
  const halfCheckedKeys = roleFuncConfig.treeRef?.getHalfCheckedKeys() as Array<number>;
  const checkedKeys = roleFuncConfig.treeRef?.getCheckedKeys() as Array<number>;
  const keys = [...halfCheckedKeys, ...checkedKeys];
  keys.shift();
  roleFuncConfig.model.role_func_ids = keys.join(",");
  await roleStore.roleFuncConfig(roleFuncConfig.model)
  ElMessage({ type: "success", message: "角色功能设置成功" });
  roleFuncConfig.isEdit = false;
}
</script>

<style scoped lang="stylus">
    .el-row
        width 100%
        .el-card
            position relative
            .btn-wrapper
                position:absolute
                top:0
                left:0
                width 100%
                height 100%
                background-color rgba(0,0,0,0.7)
                display:none
            &:hover .btn-wrapper
                display:flex
                justify-content:center
                align-items:center
                

</style>